package com.yx.backstage.manager;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yx.backstage.config.global.BizException;
import com.yx.backstage.config.global.CommonResult;
import com.yx.backstage.enums.IntBoolean;
import com.yx.backstage.enums.Sex;
import com.yx.backstage.model.SysUser;
import com.yx.backstage.model.SysUserRoleRelation;
import com.yx.backstage.model.param.SysUserParam;
import com.yx.backstage.model.vo.SysUserVo;
import com.yx.backstage.service.SysUserRoleRelationService;
import com.yx.backstage.service.SysUserService;
import com.yx.backstage.util.JwtUtil;
import com.yx.backstage.util.LoginUtil;
import com.yx.backstage.util.TimeFormat;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author YangXiong
 */
@Slf4j
@Component
public class SysUserManager {
    @Resource
    private SysUserService sysUserService;
    @Resource
    private DictManager dictManager;
    @Resource
    private RedisTemplate<String, String> redisTemplate;
    @Resource
    private LoginUtil loginUtil;
    @Resource
    private SysUserRoleRelationService userRoleRelationService;
    @Resource
    private PasswordEncoder bCryptPasswordEncoder;

    public CommonResult<SysUserVo> getUserByName(String name) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<SysUser>();
        queryWrapper.eq(SysUser::getUserName, name);
        SysUser one = sysUserService.getOne(queryWrapper);
        SysUserVo result = sysUserToVo(one);
        return CommonResult.success(result);
    }

    private SysUserVo sysUserToVo(SysUser one) {
        SysUserVo vo = new SysUserVo();
        vo.setId(one.getId());
        vo.setAvatar(one.getAvatar());
        vo.setAccount(one.getAccount());
        vo.setUserName(one.getUserName());
        vo.setBirthday(DateUtil.format(one.getBirthday(), TimeFormat.DATE_FORMAT));
        vo.setEmail(one.getEmail());
        vo.setPhone(one.getPhone());
        vo.setHobby(dictManager.getTextByValue(one.getHobby()));
        vo.setSex(Sex.getValueByKey(one.getSex()));
        vo.setEnable(one.getEnable());
        SysUser userServiceById = sysUserService.getById(one.getUpdateUser());
        if (Objects.nonNull(userServiceById)) {
            vo.setOperatorName(userServiceById.getUserName());
        }
        vo.setCreateTime(DateUtil.format(one.getCreateTime(), TimeFormat.TIME_FORMAT));
        vo.setModifyTime(DateUtil.format(one.getUpdateTime(), TimeFormat.TIME_FORMAT));
        vo.setLastLoginTime(DateUtil.format(one.getLastLoginTime(), TimeFormat.TIME_FORMAT));
        return vo;
    }

    public CommonResult<List<SysUserVo>> page(SysUserParam param) {
        Page<SysUser> userPage = new Page<>(param.getCurrentPage(), param.getTotalPage());
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotEmpty(param.getUserName()), SysUser::getUserName, param.getUserName());
        wrapper.like(StringUtils.isNotEmpty(param.getPhone()), SysUser::getPhone, param.getPhone());
        wrapper.eq(SysUser::getIsManager, IntBoolean.YES.getKey());
        Page<SysUser> page = sysUserService.page(userPage, wrapper);
        List<SysUserVo> result = handlerResult(page.getRecords());
        return CommonResult.success(result, page.getTotal());
    }

    private List<SysUserVo> handlerResult(List<SysUser> records) {
        List<SysUserVo> vos = new ArrayList<>();
        records.forEach(one -> {
            SysUserVo vo = sysUserToVo(one);
            vos.add(vo);
        });
        return vos;
    }

    public CommonResult<String> save(SysUserParam param) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getAccount, param.getAccount())
                .eq(SysUser::getIsManager, IntBoolean.YES.getKey());
        SysUser user = sysUserService.getOne(queryWrapper);
        if (Objects.nonNull(user)) {
            throw new BizException("账号已经存在，换一个试试");
        }
        SysUser user1 = getUser(param);
        boolean save = sysUserService.save(user1);
        //成功之后设置权限
        boolean ok = setRole(user1);
        if (save && ok) {
            return CommonResult.success("新增成功");
        }
        return CommonResult.fail("新增失败，请稍后重试");
    }

    private boolean setRole(SysUser sysUser) {
        SysUserRoleRelation userRoleRelation = new SysUserRoleRelation();
        userRoleRelation.setRoleId(1L);
        userRoleRelation.setUserId(sysUser.getId());
        return userRoleRelationService.save(userRoleRelation);
    }

    private SysUser getUser(SysUserParam user) {
        SysUser currentUser = loginUtil.getCurrentUser();
        SysUser sysUser = new SysUser();
        sysUser.setId(user.getId());
        sysUser.setAvatar(user.getAvatar());
        sysUser.setUserName(user.getUserName());
        sysUser.setAccount(user.getAccount());
        sysUser.setPhone(user.getPhone());
        sysUser.setSex(Sex.getKeyByValue(user.getSex()));
        try {
            sysUser.setBirthday(DateUtil.parse(user.getBirthday()));
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new BizException("日期格式错误");
        }
        sysUser.setEmail(user.getEmail());
        sysUser.setCreateUser(user.getId());
        sysUser.setIsManager(IntBoolean.YES.getKey());
        sysUser.setUpdateUser(currentUser.getId());
        if (Objects.nonNull(user.getPassword())) {
            sysUser.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
        }
        sysUser.setHobby(dictManager.getKeyByValue(user.getHobby()));
        return sysUser;
    }

    public CommonResult<List<SysUserVo>> getUserList(SysUserParam param) {
        Page<SysUser> userPage = new Page<>(param.getCurrentPage(), param.getTotalPage());
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotEmpty(param.getUserName()), SysUser::getUserName, param.getUserName());
        wrapper.eq(StringUtils.isNotEmpty(param.getHobby()),SysUser::getHobby, dictManager.getKeyByValue(param.getHobby()));
        wrapper.like(StringUtils.isNotEmpty(param.getPhone()), SysUser::getPhone, param.getPhone());
        wrapper.eq(SysUser::getIsManager, IntBoolean.NO.getKey());
        Page<SysUser> page = sysUserService.page(userPage, wrapper);
        List<SysUserVo> result = handlerResult(page.getRecords());
        return CommonResult.success(result, page.getTotal());
    }

    public Boolean updateStatus(SysUserParam param) {
        SysUser sysUser = sysUserService.getById(param.getId());
        if (Objects.isNull(sysUser)){
            throw new BizException("非法操作，用户不存在");
        }
        UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", param.getId());
        updateWrapper.set("enable", param.getEnable());
        return sysUserService.update(updateWrapper);
    }

    public Boolean deleteUser(SysUserParam param) {
        if(Objects.isNull(param.getId())){
            throw new BizException("参数不能为空");
        }
        SysUser message = sysUserService.getById(param.getId());
        if(Objects.isNull(message)){
            throw new BizException("非法操作，用户不存在");
        }
        return sysUserService.removeById(param.getId());
    }

    public CommonResult<Map<String,String>> updateUser(SysUserParam user) {
        SysUser sysUser = getUser(user);
        log.info("User={}", sysUser);
        boolean update = sysUserService.updateById(sysUser);
        if (update) {
            //拿到最新信息
            SysUser user1 = sysUserService.getById(user.getId());
            //删除缓存
            redisTemplate.delete("login:"+user1.getId());
            Map<String, String> map = new HashMap<>(2);
            map.put("message", "编辑成功");
            String token = JwtUtil.createJwt(user1.getId().toString());
            map.put("token", token);
            map.put("userName", user1.getUserName());
            map.put("avatar", user1.getAvatar());
            return CommonResult.success(map);
        }
        return CommonResult.fail("编辑失败");
    }
}
